/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package main;

import helper.Utilities;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.ArrayList;
import model.Request;
import model.Response;
import model.Torrent;

/**
 *
 * @author Hallucinogen
 */
public class Peer {
    public Peer(){
        /** peer kosongan */
    }

    /// TODO : peer cuma butuh IP Address, ga butuh port
    public Peer(String trackerAddress){
        m_TrackerAddress = trackerAddress;
    }

    public Response requestFileToTracker(String torrentName) throws IOException{
        Torrent torrent = new Torrent(torrentName);
        Request request = new Request(torrent);

        return requestFileToTracker(request);
    }

    public Response requestFileToTracker(Request request) throws IOException{
        m_Data = request;
        String reqStr  = "?" + request.encodeRequest();
        String urlStr   = "http://" + m_TrackerAddress + ":" + Utilities.TRACKER_PORT + "/" + reqStr;
        URL url = new URL(urlStr);
        HttpURLConnection con = (HttpURLConnection)url.openConnection();

        DataInputStream dis = new DataInputStream(con.getInputStream());
        BufferedInputStream bis = new BufferedInputStream(dis);

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < con.getContentLength(); ++i)
            sb.append((char)bis.read());

        m_LastRequest = System.currentTimeMillis();

        return Response.decodeResponse(sb.toString());
    }

    public boolean requestFileToPeer(String fileName){

        return false;
    }

    public boolean requestFileToPeer(String fileName, int part){

        return false;
    }

    public static int getCompletePeersCount(ArrayList<Peer> peers) {
        int cnt = 0;

        if (peers == null) return 0;

        for (Peer peer : peers) {
            if (peer.getData().getLeft() == 0)
                ++cnt;
        }

        return cnt;
    }

    public static int getIncompletePeersCount(ArrayList<Peer> peers) {
        int cnt = 0;

        if (peers == null) return 0;

        for (Peer peer : peers) {
            if (peer.getData().getLeft() > 0)
                ++cnt;
        }

        return cnt;
    }

    public static void main(String args[]) throws IOException{
        Peer peer = new Peer("127.0.0.1");

        //Response resp = peer.requestFileToTracker("res/Tugas_Besar_1_IF3056.pdf.torrent");
        peer.startHandler();

        /*for (int i = 0; i < 10; ++i){
            resp = peer.requestFileToTracker("res/Tugas_Besar_1_IF3056.pdf.torrent");
            for (int j = 0; j < resp.getPeers().size(); ++j){
                System.out.println(resp.getPeers().get(j).m_Address);
            }
            try {
                Thread.sleep(Utilities.PEER_REQUEST_INTERVAL);
            } catch (InterruptedException ex){
                
            }
        }

        peer.stopHandler();

        for (int i = 0; i < resp.getPeers().size(); ++i){
            System.out.println(resp.getPeers().get(i).m_Address);
        }*/
    }

    public void setData(Request data) {
        m_Data = data;
    }

    public Request getData(){
        return m_Data;
    }

    public void setAddress(InetSocketAddress addr){
        m_Address = addr;
    }

    public InetSocketAddress getAddress(){
        return m_Address;
    }

    public long getLastRequest(){
        return m_LastRequest;
    }

    public Response getResult() {
        return m_Result;
    }

    public void setLastRequest(long time) {
        m_LastRequest = time;
    }

    public void startHandler(){
        m_PeerHandler = new PeerThread(this);

        /** start now */
        m_PeerHandler.start();
    }

    public void setResult(Response result) {
        m_Result = result;
    }

    public void stopHandler(){
        if (m_PeerHandler == null) return;

        /** try joining last thread */
        m_PeerHandler.setRunning(false);
        boolean join = false;

        while (!join) {
            try {
                m_PeerHandler.join();
                join = true;
            } catch (InterruptedException ex){
                // do nothing
            }
        }
    }
    
    private String m_TrackerAddress;
    private Request m_Data;
    private Response m_Result;
    private InetSocketAddress m_Address;
    private long m_LastRequest;
    private PeerThread m_PeerHandler;
}
